package org.hk.proxy.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import org.hk.proxy.client.config.ClientConfig;
import org.hk.proxy.client.listener.ProxyChannelBorrowListener;
import org.hk.proxy.common.constant.CommonKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class ClientChannelManagement {
    private static  final Logger log = LoggerFactory.getLogger(ClientChannelManagement.class);
    public static final ConcurrentLinkedQueue<Channel> proxyChannels = new ConcurrentLinkedQueue<>();
    public static final Integer MAX_CHANNEL_SIZE = 500;
    public static volatile  Channel cmdChannel;
    public static void borrowChannel(Bootstrap proxyBootStrap, ProxyChannelBorrowListener listener){
        Channel proxyChannel = proxyChannels.poll();
        if(proxyChannel!=null){
            listener.success(proxyChannel);
            return;
        }else {
            proxyBootStrap.connect(ClientConfig.CLIENT_CONFIG.getServerIp(),ClientConfig.CLIENT_CONFIG.getServerPort()).addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if(future.isSuccess()){
                        Channel newProxyChannel = future.channel();
                        log.info("客户端开启数据连接：{}",newProxyChannel);
                        listener.success(newProxyChannel);
                    }else {
                        listener.error(future.cause());
                    }
                }
            });
        }
    }

    public static void returnProxyChannel(Channel proxyChannel){
        if(proxyChannels.size()<MAX_CHANNEL_SIZE&&proxyChannel!=null){
            proxyChannel.config().setOption(ChannelOption.AUTO_READ, true);
            proxyChannel.attr(CommonKey.REAL_PROXY).set(null);
            proxyChannels.offer(proxyChannel);
            log.info("return proxyChannel to the pool, channel is {}, pool size is {}",proxyChannel,proxyChannels.size());
        }else {
            proxyChannel.close();
        }
    }
}
